-- 索引

    -- 创建索引相关关键字：
        -- create 创建索引
        -- unque 唯一
        -- nonclustered 非聚集索引
        -- clustered 聚集索引
        -- on 表 ( 字段 desc/asc ) 在某某表内的字段 降序/升序
        -- fillfactor 填充因子
        -- drop_existing 删除并重新创建已命名的索引

    -- 例子：
        -- 1.在课程表的课程名上建立一个唯一的非聚集索引
        -- name——v1 降序 填充因子75%
        create unique nonclustered index name_v1
        on 课程表 (课程名 desc)
        with fillfactor=75

        -- 2.在学生表的学号上建立一个唯一的聚集索引v1,
        -- 升序,填充因子50%
        create unique clustered index v1 
        on 学生表(学生号 asc) 
        with fillfactor=50

        -- 3.在课程表的学时(降序),学分(降序)上建立一个
        -- 非聚集索引v2,填充因子85%
        create nonclustered index v2
        on 课程表(学时 desc ,学分 desc)
        with fillfactor=85

        -- 查看索引
        -- sp_helpindex 表名
        -- 重命名索引
        -- sp_rename 表名.原索引名,新索引名
        -- 删除索引
        -- drop index 表名.索引名
        -- 如果所有是在create table语句中创建地,
        -- 只能用alter table命令来删除索引

-- 视图
    -- 优点：
        -- 限定特定的数据
        -- 简化数据操作
        -- 安全保护
    -- 缺点
        -- 降低性能
        -- 限制修改
    -- 视图创建与管理
        -- 语法格式：
            create view 视图名
            [with encryption]
            as select 语句
            [with check option]
        -- 说明：
            [with encryption]:--对试图地定义进行加密
            [with check option]:-- 强制通过试图执行的所有数据修改语句必须符合试图定义中设置的条件
        -- 例子:
            -- 1.在教务管理数据库的学生表上船舰一个xs_view1视图
            -- 试图中只包括所有政治面貌为 "共产党员" 的学生信息
            use 教务管理数据库
            go
            create view xs_view1
            as 
            select * 
            from 学生表 
            where 政治面貌="共产党员"

            -- 2.在教务管理数据库的学生表上船舰一个xs_view2视图
            -- 试图中只包括 学号 姓名 性别 政治面貌等信息
            use 教务管理数据库
            go
            create view xs_view2
            as 
            select 学号,姓名,性别,政治面貌
            from 学生表 

            -- 3.在教务管理数据库的学生表,选课表上创建一个xs_view3视图
            -- 试图中只包括jy071班级学生的的学号,姓名,班级,课程号等信息
            use 教务管理数据库
            go
            create view xs_view3
            as
            select 学号,姓名,班级,课程号
            from 学生表,选课表 
            where 学生表.学号=选课表.学号

            -- 4.在教务管理数据库的学生表上创建一个xs_view4视图
            -- 视图中每个学生的学号和所学课程的总成绩
            use 教务管理数据库
            go
            create view xs_view4
            as select 学号,sum(成绩) as 总成绩
            from 选课表
            group by 学号

            -- 5.在教务管理数据库中创建视图xs_view5
            -- 视图中只包含女生的学号,姓名,性别,政治面貌
            use 教务管理数据库
            go
            create view xs_view5
            as select 学号,姓名,性别,政治面貌
            from 学生表
            where 性别="女生"

    -- 修改视图内容
        -- 语法格式：
            alter view 视图名
            [with encryption]
            as select 语句
            [with check option]
        -- 例子：
            -- 修改教务管理数据库中的xs_view1视图
            -- 视图只包含所有政治面貌为"共青团员"的学生信息
            use 教务管理数据库
            go
            alter view xs_view1
            as 
            select *
            from 学生表
            where 政治面貌="共青团员"

    -- 删除视图
        -- 语法
            drop view 视图名
        -- 例子：
            -- 删除教务管理数据库中的xs_view1视图
            drop view xs_view1

    -- 重命名视图
        -- 语法
            sp_rename 原视图名,新视图名
        -- 例子
            -- 将教务管理数据库中的"xs_view4"视图重命名为"xs_view2"
            sp_rename xs_view4,xs_view2
            
    -- 通过视图查询数据
        -- 语法格式
            select 字段名列表|* from 视图名
        -- 例子
            -- 1.查询"xs_view3"视图中的所有信息
            select * from xs_view3
            -- 2.查询"xs_view3"视图中的所有学号,姓名和课程号
            select 学号,姓名,课程号 from xs_view3
            
    -- 通过视图插入数据
        -- 语法格式
            insert 视图名 [(列名,...)] 
            values(值,...)
        -- 例子
            -- 向"xs_view2"视图中插入一行数据
            insert xs_view2 
            values('20070401101','黎明','男','共青团员')

    -- 通过视图查询或更改数据
        -- 语法格式
            update 视图名
            set 列名=表达式[,...n]
            [where<条件>]
        -- 说明：
            -- 可以一次修改多个字段,如果有条件子句,
            -- 只修改满足条件的行,否则所有行都被修改
        -- 例子
            -- 将"xs_view2"视图中学号为"20070401101"的
            -- 学生的政治漫猫改为"共产党员"
            update xs_view2
            set 政治面貌='共产党员'
            where 学号='20070401101' 

    -- 通过视图删除数据
        -- 语法格式
            delete [from] 视图名 [where]<条件>
        -- 如果有条件子句,只删除视图中满足条件的行,否则视图中所有行都被删除
        -- 例子
            -- 将"xs_view2"视图中学号为"20070401101"的数据行删除
            delete xs_view2 where 学号='20070401101'

    -- 通过视图更新数据的限制
        -- 使用视图可以更改基表中的数据,但是使用视图修改数据hi,
        -- 有以下几点限制：
            -- 1.
                -- 修改视图中的数据时,不能同时修改两个或多个基表,
                -- 可以对基于两个或多个基表或视图的视图进行修改,
                -- 但是每次修改都稚嫩影响一个基表
            -- 2.
                -- 不能修改那些通过计算得到的字段
            -- 3.
                -- 如果在创建视图时指定了with check option选项,
                -- 那么所有使用视图修改数据库信息时,
                -- 必须保证修改后的数据满足视图定义的范围
            -- 4
                -- 执行update,delete命令时,
                -- 所删除与个更新的数据必须包含在视图的结果集中
            -- 5
                -- 如果视图引用多个表时,无法用delete命令删除数据
-- 用户定义函数
    -- 概念和分类
        -- 在sql server中,除了系统内置的函数外,用户可以在数据库中自己定义函数
        -- 用户自定义函数是由一个或多个sql语句组成的子程序,它可以接收参数,执行操作,并将擦过结果以值的形式返回
        -- sql server的用户定义函数分为两类：标量值函数,表值函数.表值函数又分为内嵌表值函数和多语句表值函数
    -- 在 sql server 中使用用户定义函数有以下优点：
        -- 1.允许模块化程序设计
        -- 2.执行熟读更快
        -- 3.减少网络流量
    -- 创建和使用标量值用户定义函数
        -- 标量值用户定义函数返回单个数值,即标量值,
        -- 但会类型可以是除 text,ntext,image,cursor 和 timestamp外的任何数据类型
        -- 1.创建标量值用户定义函数
            -- (1)用T_sql语句创建
                -- 语法格式
                    create function 函数名([[@参数名 as ]参数类型[,...n]])
                    returns 返回值类型
                    begin 
                        函数体
                        return 标量表达式
                    end
                -- 例子
                    create function 某专业男女比例(@专业名 varchar(20))
                    returns numeric(6,2)
                    as
                    begin
                        declare @main int 
                        declare @woman int
                        -- 统计男生人数
                        select @man=count(*)
                        from 学生表,专业表,班级表
                        where 学生表.班级=班级表.班号 and 班级表.专业=专业表.专业好 and 性别="男" and 专业=@专业名
                        -- 统计班级女生人数
                        select @man=count(*)
                        from 学生表,专业表,班级表
                        where 学生表.班级=班级表.班号 and 班级表.专业=专业表.专业好 and 性别="女" and 专业=@专业名
                        returns cast(@man as float)/cast(@woman as float)
                    end
        -- 2.创建和使用表值用户定义函数
            -- 内嵌表值用户定义函数返回一个select语句查询的结果集,是table数据类型
            -- 创建内嵌表值函数
                -- 用t——sql语句创建
                -- 语法格式：
                    create function 函数名([[@参数名 as]参数类型])
                    returns table
                    return 查询语句
                -- 例子
                    -- 创建用户定义函数,其功能是可用于查看某班某课程的成绩单
                        use 教务管理数据库
                        go
                        create function 某班某课成绩单(
                            @班名 char(20),
                            @课程名 varchar(20)
                        )
                        returns table
                        as
                        return
                            select 班名,学生表.学号,姓名,课程名.成绩
                            from 班级表,客场表,选课表,学生表
                            where 课程表.课程号=选课表.课程号 asd 学生表.学号=选课表.学号
            -- 修改用户定义函数
                alter function(@参数 类型)
                returns table
                as
                    returns
                        select...
            -- 删除用户定义函数
                drop function(@参数 类型)

-- 存储过程
    -- 概念
        -- 存储过程时存储哎sql server服务器中的一组与编译过的t-sql语句组成的模块，用来完成某项特定的功能
        -- 存储过程可以接受输入参数并以输出参数的格式向调用过程或批处理返回多个值
        -- ...
    -- 优点
        -- 1.执行速度快
        -- 2.提高系统安全性
        -- 3.程序设计模块化
        -- 4.减少网路通信流量  
    -- 语法
        -- 创建
            create proc[edure] 存储过程名[@参数 数据类型]
            as
            begin
                sql 语句
            end
        -- 修改
            alter proc[edure] 存储过程名[@参数 数据类型]
            as
            begin
                sql 语句
            end
        -- 删除
            drop procedure 存储过程名[@参数 数据类型]

-- 触发器 
    -- 概念 
        -- 触发器是一种特殊地存储过程，它不带任何地输入输出参数，不能被显示调用
        -- 触发器与特定大的sql server对象相关联，在这些对象的制定操作发生时
        -- 服务器自动执行该触发器
    -- 分类
        -- ddl触发器
        -- dml触发器
    -- 用t-sql语句创建触发器
        create trigger 触发器名
        on 表名|视图名
        {for|after|instead of}
        {[insert][,][update][,][delete]}
        as
        sql 语句
    -- 修改
        alter trigger
        on 表名|视图名
        {for|after|instead of}
        {[insert][,][update][,][delete]}
        as
        sql 语句
    -- 删除
        drop trigger
        on 表名|视图名
        {for|after|instead of}
        {[insert][,][update][,][delete]}
        as
        sql 语句  
-- 游标
    -- 概念
        -- 游标是一种可以凑够包含多条记录的结果集中逐条访问数据行的机制
        -- 利用游标.可以定位 检索或修改特定的行
        -- 游标由结果集和结果集中只想特定记录的游标位置(可以理解为一个位置指针)组成
        -- Transact-sql 游标主要用在存储过程,触发器和Transact-sql脚本中
    -- 语法
        -- 声明游标
            declare 游标名 cursor
            [local|global|forward_only|scroll]
            [static|dynamic][read_obly]
            for select 语句
            [for update [of 列名]]

